TypeScript 筆記:never 簡介


Posted by SimonAllen on 2021-08-18

上一篇 TypeScript 筆記簡單介紹了 unknown,而此篇改來介紹另一個特殊型別—— never:

never

never 型別是所有型別的子集,TypeScript 「所有」型別(甚至包括 any、null 與 undefined)都有包含 never 例外處理的狀態,其在 TypeScript 2.0 版提出,表示不存在值的型別,那怎樣會出現不存在值的型別呢?

最常見的情形有兩種:

  • 無法結束的函式方法
  • throw error 錯誤處理

無法結束的函式方法

無法結束函式方法情境,最常見就是函式內發生了無限迴圈的情況:

function infiniteLoop(){
   while(true){
   }
}

不過,上述程式碼在型別推論因為函式沒有回傳值,會被自動推論成 void。

可以這麼理解,當一個函式沒有返回值時,它的 return 值為 void 型別,但是當一個函式要 return 的返回值(例如表達式)卻沒有也永不返回(或者拋出錯誤),它的返回值為 never 型別。

若上述看起來很咬舌頭,可看看以下程式為例:

當函式被當成值指派給變數時,型別推論就幫我們推測變數為 never 型別。

const infinity = function infiniteLoop() {
  while (true) {}
};

throw error 錯誤處理

另一個情境就是 throw error 錯誤拋出時

function throwNewError(){
   throw new Error("error")
}

上述程式碼一樣在型別推論時,沒有回傳值被自動推論成 void。

當函式被當成值指派給變數時,型別推論就幫我們推測變數為 never 型別。

const error = function throwNewError() {
  throw new Error("error");
};

不管是型別推論或主動註記, never 可以幫助開發者提醒有可能會發生錯誤的狀況,非常貼心。

另外前面有提到所有型別(包括 any)都有包含 never 例外處理的狀態,所以在做聯合型別時,never 的優先度很低:

type stringAndNever = string | never;

聯合型別為 string,至於聯合型別與上方寫的 type 是做什麼,之後有機會再撰寫新的筆記季紹。

而和 any 相比

型別推論會推測此聯合型別為 any

和 undefined 相比

type undefinedAndNever = undefined | never;


聯合型別為 undefined。

和 null 聯合型別放一起也是 null,截圖就不放了。因為所有型別都包含著 never(作為例外處理的狀況),所以 never 永遠會被忽略,前面有提到 never 是表示不會存在值的型別,而 null 和 undefined 既是值也是型別,所以 never 也是 null 和 undefined 子集合。

正因如此,若我們主動註記 never 給變數再賦值

const a: never = 1
const b: never = "1"
const c: never = null
const d: never = undefined

這四個變數會全報錯,因為 never 是所有型別子集合,但其他型別不是 never 子集合,這個上對下的關係要搞清楚呦。

參考

TypeScript 新手指南
TypeScript: Typed JavaScript at Any Scale.
kobo 電子書:讓TypeScript成爲你前端開發的ACE!
Typescript 初心者手札


#TypeScript









Related Posts

JS30 Day 20 筆記

JS30 Day 20 筆記

淺談 JavaScript 中的時間與時區處理

淺談 JavaScript 中的時間與時區處理

1661. Average Time of Process per Machine

1661. Average Time of Process per Machine


Comments